home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_gen / gcoope10.zip / CLASS.C < prev    next >
Text File  |  1994-07-23  |  6KB  |  267 lines

  1. /*
  2.  
  3.     This is the pseudo class definition for Class for GCOOPE Ver 1.0.
  4.  
  5.                  by Brian Lee Price
  6.  
  7.         Released as Public Domain   July, 1994.
  8.  
  9. */
  10.  
  11. #define __CLASS_DEFINITION__
  12.  
  13. #include "gcstruct.h"
  14.  
  15. #include <stdarg.h>
  16.  
  17.  
  18. /*
  19. AVAILABLE FOR EXTERNAL USE.
  20.  
  21.     This routine's main use is to inherit the ancestor methods for
  22.     a new class.  However, it can be called by a pseudo-class or an
  23.     actual class definition to inherit only the methods (not the
  24.     instance variables) of a non-ancestor class.  I'm not sure of what
  25.     practical use it will be used in this manner, but... who knows?
  26. */
  27.  
  28. stat inhMthd(object class, object super)
  29. {
  30. int        numPar;
  31. int        numMthds;
  32. superEntry *    parent;
  33. classEntry *    clsEnt;
  34. methodEntry *    meths;
  35. stat        retVal=FUNCFAIL;
  36.  
  37.  
  38. if(class==Object || super==Object || NULL==(clsEnt=getObjDef((tag)super)))
  39.     goto end;
  40. (char *) parent=&(clsEnt->cVars[clsEnt->cvSize]);
  41. numPar=clsEnt->numSuper;
  42. numMthds=clsEnt->numMthds;
  43. parent+=numPar;
  44. (superEntry *) meths = parent;
  45. numPar--;
  46. parent--;
  47. for(;numPar>=0;numPar--,parent--)
  48.     {
  49.     if(inhMthd(class,parent->class)) goto end;
  50.     }
  51. for(;numMthds>0;numMthds--,meths++)
  52.     {
  53.     if(addMethod(meths->genTag,meths->clsMthd,(tag) class,
  54.     (tag) super)) goto end;
  55.     }
  56. retVal=FUNCOKAY;
  57.  
  58. end:
  59. return retVal;
  60. }
  61.  
  62.  
  63. /*
  64. AVAILABE VIA CALL TO New with Class as the instance object.
  65.  
  66.     This routine creates a new class, installing it into the
  67.     object system.
  68.  
  69. */
  70.  
  71. static object newClass(object instance, int cvSize, int ivSize,...)
  72. {
  73. va_list        ap;
  74. int        totSz;
  75. int         numPar=0;
  76. object        temp;
  77. classEntry *    clsEnt;
  78. classEntry *    parEnt;
  79. superEntry *    parent;
  80. int        curOff;
  81.  
  82. totSz=sizeof(classEntry)+cvSize+(sizeof(methodEntry)*MIN_METHOD_ADD);
  83. va_start(ap,ivSize);
  84. while(END!=(temp=va_arg(ap,object)))
  85.     {
  86.     if(NULL==(clsEnt=getObjDef((tag) temp))) goto err1;
  87.     if(clsEnt->class!=(tag) instance) goto err1;
  88.     numPar++;
  89.     }
  90. va_end(ap);
  91. totSz+= sizeof(superEntry)*numPar;
  92. clsEnt=s_calloc(1,totSz);
  93. clsEnt->cvSize=cvSize;
  94. clsEnt->ivSize=curOff=ivSize;
  95. curOff+=sizeof(int);
  96. clsEnt->numSuper=numPar;
  97. clsEnt->numMthds=0;
  98. clsEnt->loadAdr=NULL;
  99. clsEnt->class=(tag) instance;
  100. if(((tag)instance=addObject(clsEnt,PERM_PROC_ID))<0) goto err2;
  101. (char *) parent= &(clsEnt->cVars[clsEnt->cvSize]);
  102.  
  103. va_start(ap,ivSize);
  104. for(;numPar>0;numPar--,parent++)
  105.     {
  106.     temp=va_arg(ap,object);
  107.     parEnt=getObjDef(parent->class=(tag) temp);
  108.     parent->offset=curOff;
  109.     curOff+=parEnt->totSize;
  110.     }
  111. clsEnt->totSize=curOff;
  112. if(inhMthd(instance,instance)) goto err3;
  113. return instance;
  114.  
  115. err3:
  116. rmvObject((tag)instance);
  117. err2:
  118. s_free(clsEnt);
  119. err1:
  120. return (object) END;
  121. }
  122.  
  123.  
  124. /*
  125. AVAILABLE FOR EXTERNAL USE.
  126.  
  127.     This routine adds a method to a generic function, if the
  128.     function does not yet exist, it will create it.
  129.  
  130. */
  131.  
  132. stat addGMthd(object class, generic genTag, method addMth)
  133. {
  134. classEntry *     clsEnt;
  135. superEntry *    parEnt;
  136. methodEntry *    mthEnt;
  137. objectEntry *    objEnt;
  138. stat        retVal=FUNCFAIL;
  139.  
  140. if((method) NULL == addMth ||
  141.     NULL==(clsEnt=getObjDef((tag) class)) || class==Object) goto end;
  142. if(addMethod(genTag, addMth, (tag) class, (tag) class)) goto end;
  143. if(NULL==(clsEnt=getObjDef((tag) class)) || clsEnt->class!=Class)
  144.     {
  145.     rmvMethod(genTag, (tag) class);
  146.     goto end;
  147.     }
  148. if(clsEnt->numMthds && !(clsEnt->numMthds%MIN_METHOD_ADD))
  149.     {
  150.     clsEnt=s_realloc(clsEnt, sizeof(classEntry) + clsEnt->cvSize +
  151.     sizeof(superEntry)*clsEnt->numSuper +
  152.     sizeof(methodEntry)*(clsEnt->numMthds + MIN_METHOD_ADD));
  153.     objEnt=getObject((tag) class);
  154.     objEnt->objDef=clsEnt;
  155.     }
  156. (char *) parEnt = &(clsEnt->cVars[clsEnt->cvSize]);
  157. parEnt+=clsEnt->numSuper;
  158. mthEnt=(methodEntry *) parEnt;
  159. mthEnt+=clsEnt->numMthds;
  160. mthEnt->genTag=genTag;
  161. mthEnt->clsMthd=addMth;
  162. clsEnt->numMthds++;
  163.  
  164. retVal=FUNCOKAY;
  165. end:
  166. return retVal;
  167. }
  168.  
  169.  
  170. stat cpyGMas(object newClass, generic newGenFunc,
  171.         object oldClass, generic oldGenFunc)
  172. {
  173. genMethod *    oldRcd;
  174.  
  175. if(NULL==(oldRcd=getMthd(oldGenFunc, (tag) oldClass))) goto err;
  176. if(addGMthd(oldRcd->owner, newGenFunc, oldRcd->instMethod)) goto err;
  177. if(addMethod(newGenFunc, oldRcd->instMethod, (tag) newClass,
  178.     (tag) oldRcd->owner)) goto err;
  179. return FUNCOKAY;
  180.  
  181. err:
  182. return FUNCFAIL;
  183. }
  184.  
  185.  
  186. /*
  187. AVAILABLE FOR EXTERNAL USE.
  188.  
  189.     The prime use of this function is to block an ancestor
  190.     generic from directly acting on the main instance.
  191. */
  192.  
  193. stat rmvGMthd(object class, generic genTag)
  194. {
  195.  
  196. if(class==Object) return FUNCFAIL;
  197. return rmvMethod(genTag, (tag) class);
  198. }
  199.  
  200.  
  201. /*
  202. AVAILABLE AS THE METHOD FOR Kill with the instance == Class
  203.  
  204.     This routine will remove a class from the system, it will
  205.    also remove any ancestors which become dereferenced and will
  206.    indirectly remove all generics which become dereferenced.
  207. */
  208.  
  209. static object killClass(object instance, object class)
  210. {
  211. classEntry *     clsEnt;
  212. methodEntry *    mthEnt;
  213. int        retVal=FUNCFAIL;
  214. int        x;
  215.  
  216. if(NULL==(clsEnt=getObjDef((tag) class))) goto end;
  217. if(clsEnt->class!=Class) goto end;
  218.  
  219. (char *) mthEnt = &(clsEnt->cVars[clsEnt->cvSize]);
  220. (superEntry *) mthEnt +=clsEnt->numSuper;
  221. for(x=clsEnt->numMthds;x>0;x--,mthEnt++)
  222.     {
  223.     rmvMethod(mthEnt->genTag, (tag) instance);
  224.     }
  225.  
  226. rmvObject((tag) class);
  227. retVal=FUNCOKAY;
  228.  
  229. end:
  230. return (object) retVal;
  231. }
  232.  
  233.  
  234.  
  235. /*
  236. FOR KERNEL USE ONLY.
  237.  
  238.     This routine installs the pseudo class Class.
  239. */
  240.  
  241.  
  242. stat Class_Install(void)
  243. {
  244. stat            retVal=FUNCFAIL;
  245. classEntry *        clsEnt;
  246.  
  247. Class=(object) 1;
  248. if((object) END == (Class=newClass(Class,0,0,END))) goto end;
  249. if(Class!=1)
  250.     {
  251.     if(NULL==(clsEnt=getObjDef((tag) Class))) goto err;
  252.     clsEnt->class=(tag) Class;
  253.     }
  254. if(addMethod(New,(method) newClass, (tag) Class, (tag) Class)) goto err;
  255. if(addMethod(Kill,(method) killClass, (tag) Class, (tag) Class)) goto err;
  256. retVal=FUNCOKAY;
  257.  
  258. end:
  259. return retVal;
  260.  
  261. err:
  262. killClass(Class, Class);
  263. return retVal;
  264. }
  265.  
  266.  
  267.